<template>
  <view class="chat-container">
    <!-- 消息列表 -->
    <scroll-view class="message-list" scroll-y>
      <view v-for="(msg, index) in messages" :key="index" class="message-item">
        <text>{{ msg.type === 'text' ? msg.content : '[语音消息]' }}</text>
      </view>
    </scroll-view>

    <!-- 输入区域 -->
    <view class="input-container">
      <!-- 模式切换按钮 -->
      <uni-icons 
        :type="isVoiceMode ? 'color' : 'phone'" 
        size="24" 
        color="#07C160"
        @click="toggleInputMode"
      />

      <!-- 文本输入框 -->
      <textarea
        v-if="!isVoiceMode"
        v-model="inputText"
        @input="adjustTextareaHeight"
        @keypress.enter.prevent="sendText"
        :style="{ height: textareaHeight + 'px' }"
        class="input-textarea"
        placeholder="请输入消息"
        cursor-spacing="10"
        confirm-type="send"
      />

      <!-- 语音按钮 -->
      <view
        v-else
        class="voice-btn"
        @touchstart.prevent="startRecording"
        @touchend.prevent="stopRecording"
        @touchmove.prevent="handleTouchMove"
        :class="{ 'recording': isRecording, 'canceling': isCanceling }"
      >
        <text>{{ buttonText }}</text>
        <view v-if="isRecording" class="voice-wave"></view>
      </view>

      <!-- 发送按钮 -->
      <button
        v-if="!isVoiceMode && inputText.trim()"
        class="send-btn"
        @click="sendText"
      >发送</button>
    </view>
  </view>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'

// 数据状态
const isVoiceMode = ref(false)
const inputText = ref('')
const textareaHeight = ref(40)
const isRecording = ref(false)
const isCanceling = ref(false)
const messages = ref([])
const touchStartY = ref(0)
const recorderManager = uni.getRecorderManager()

// 录音按钮文字
const buttonText = computed(() => {
  if (isCanceling.value) return '松开取消'
  if (isRecording.value) return '松开发送'
  return '按住说话'
})

// 调整输入框高度
const adjustTextareaHeight = () => {
  const lineHeight = 20
  const maxHeight = 120
  const newHeight = Math.min(inputText.value.split('\n').length * lineHeight + 20, maxHeight)
  textareaHeight.value = Math.max(newHeight, 40)
}

// 发送文本消息
const sendText = () => {
  if (!inputText.value.trim()) return
  
  messages.value.push({
    type: 'text',
    content: inputText.value.trim(),
    time: Date.now()
  })
  
  inputText.value = ''
  textareaHeight.value = 40
  scrollToBottom()
}

// 切换输入模式
const toggleInputMode = () => {
  isVoiceMode.value = !isVoiceMode.value
  if (!isVoiceMode.value) {
    setTimeout(() => {
      uni.hideKeyboard()
    }, 100)
  }
}

// 开始录音
const startRecording = async (e) => {
  // 检查权限
  try {
    const res = await uni.getSetting({})
    if (!res.authSetting['scope.record']) {
      await uni.authorize({ scope: 'scope.record' })
    }
  } catch (err) {
    uni.showToast({ title: '麦克风权限被拒绝', icon: 'none' })
    return
  }

  isRecording.value = true
  touchStartY.value = e.touches[0].pageY
  
  recorderManager.start({
    format: 'mp3',
    duration: 60000
  })
  
  // 录音超时处理
  recorderManager.onInterruptionBegin(() => {
    uni.showToast({ title: '录音已达最大时长', icon: 'none' })
    stopRecording()
  })
}

// 停止录音
const stopRecording = () => {
  if (!isRecording.value) return
  
  recorderManager.stop()
  recorderManager.onStop((res) => {
    if (isCanceling.value) {
      uni.showToast({ title: '已取消发送', icon: 'none' })
    } else {
      messages.value.push({
        type: 'voice',
        filePath: res.tempFilePath,
        duration: res.duration,
        time: Date.now()
      })
      scrollToBottom()
    }
    
    isRecording.value = false
    isCanceling.value = false
  })
}

// 处理滑动取消
const handleTouchMove = (e) => {
  if (!isRecording.value) return
  
  const currentY = e.touches[0].pageY
  isCanceling.value = touchStartY.value - currentY > 50
}

// 滚动到底部
const scrollToBottom = () => {
  setTimeout(() => {
    const query = uni.createSelectorQuery()
    query.select('.message-list').boundingClientRect()
    query.selectViewport().scrollOffset()
    query.exec((res) => {
      if (res[0]) {
        uni.pageScrollTo({
          scrollTop: res[0].height,
          duration: 300
        })
      }
    })
  }, 100)
}

// 初始化录音管理器
onMounted(() => {
  recorderManager.onError((err) => {
    console.error('录音错误:', err)
    uni.showToast({ title: '录音失败', icon: 'none' })
    isRecording.value = false
    isCanceling.value = false
  })
})
</script>

<style scoped>
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background-color: #f5f5f5;
  box-sizing: border-box;
}

.message-list {
  flex: 1;
  padding: 12px;
  overflow: auto;
}

.message-item {
  background-color: #fff;
  padding: 8px 12px;
  border-radius: 4px;
  margin-bottom: 8px;
  max-width: 80%;
}

.input-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px;
  background-color: #fff;
  border-top: 1px solid #eee;
  box-sizing: border-box;
}

.input-textarea {
  flex: 1;
  min-height: 40px;
  max-height: 120px;
  padding: 8px;
  margin: 0 8px;
  background-color: #f5f5f5;
  border-radius: 4px;
  font-size: 16px;
}

.voice-btn {
  flex: 1;
  height: 40px;
  margin: 0 8px;
  background-color: #f5f5f5;
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.voice-btn.recording {
  background-color: #ffebee;
}

.voice-btn.canceling {
  background-color: #e0e0e0;
}

.voice-wave {
  width: 20px;
  height: 20px;
  margin-left: 8px;
  background-image: url('');
  background-size: contain;
  animation: wave 1s infinite;
}

.send-btn {
  height: 40px;
  line-height: 40px;
  padding: 0 12px;
  background-color: #07C160;
  color: white;
  border-radius: 4px;
  font-size: 14px;
}

@keyframes wave {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.2); }
}
</style>